<?php

namespace app\api\controller\v11;

use app\api\controller\v2\Auth;
use app\common\cachemodel\Goods;
use app\common\cachemodel\NatalGoods;
use app\common\cachemodel\Orders as OrdersCacheModel;
use app\common\cachemodel\OrdersGoods;
use app\common\cachemodel\Recode;
use app\common\lib\Orders as OrdersLib;
use Exception;
use think\Db;
use think\Log;
use think\response\Json;

class Orders extends Auth
{
    /**
     * 接口，获取商品信息
     * @return Json
     * @throws Exception
     */
    public function getOrderGoods()
    {
        $rid = input('rid/d', 0);
        $type = input('type/d', 0);

        switch ($type)
        {
            case 7:
                $data = (new NatalGoods())->getDownOrderGoods($this->user['id'], $rid);
                break;
            default:
                return show(config('code.error'), '服务异常');
        }

        return show(config('code.success'), '请求成功', $data);
    }

    /**
     * 接口，订单列表
     * @return Json
     * @throws Exception
     */
    public function index()
    {
        $type = input('param.type/d', 0);
        $orders = (new OrdersCacheModel())->getUserAllOrder($this->user['id'], $type, '', '8');
        if ($orders)
        {
            $orders_details = (new OrdersLib())->getOrderDetails($orders['data']);
            foreach ($orders_details as $k => $order)
            {
                if ($k)
                {
                    switch (true)
                    {
                        case $order['order_type'] == 1:
                            $rectification_data = [];
                            foreach ($order['rectification_data'] as $rectification_datum)
                            {
                                $rectification_data = [
                                    'id' => $rectification_datum['reid'],
                                    'birth' => $rectification_datum['birth'],
                                    'start_time' => $rectification_datum['start_time'],
                                    'end_time' => $rectification_datum['end_time'],
                                    'or_price' => $rectification_datum['or_price'],
                                    'now_price' => sprintf('%.2f', $rectification_datum['now_price'])
                                ];
                            }
                            $orders_details[$k]['rectification_data'] = $rectification_data;
                            break;
                        case in_array($order['order_type'], [2, 3, 4]):
                            $fortune_data = [];
                            foreach ($order['fortune_data'] as $fortune_datum)
                            {
                                $fortune_data[] = [
                                    'id' => $fortune_datum['id'],
                                    'gid' => $fortune_datum['gid'],
                                    'rname' => $fortune_datum['rname'],
                                    'fortune_type' => $fortune_datum['fortune_type'],
                                    'start_time' => $fortune_datum['start_time'],
                                    'end_time' => $fortune_datum['end_time'],
                                    'or_price' => $fortune_datum['or_price'],
                                    'now_price' => sprintf('%.2f', $fortune_datum['now_price'])
                                ];
                            }
                            $orders_details[$k]['fortune_data'] = $fortune_data;
                            break;
                        case $order['order_type'] == 5:
                            $gname = [];
                            $rname = '';
                            foreach ($order['acgmap_data'] as $acgmap_datum)
                            {
                                $gname[] = $acgmap_datum['gname'];
                                $rname = $acgmap_datum['rname'];
                            }
                            $orders_details[$k]['acgmap_data'] = [
                                'order_sub_name' => '幸运之城解锁',
                                'order_sub_rname' => $rname,
                                'order_sub_names' => implode(',', $gname),
                            ];
                            break;
                        case $order['order_type'] == 6:
                            $video_data = [];
                            foreach ($order['video_data'] as $video_datum)
                            {
                                $video_data = [
                                    'id' => 1,
                                    'order_sub_name' => '占星课程',
                                    'course_title' => $video_datum['course_title'],
                                    'or_price' => $video_datum['or_price'],
                                    'now_price' => sprintf('%.2f', $video_datum['now_price'])
                                ];
                            }
                            $orders_details[$k]['video_data'] = $video_data;
                            break;
                        case $order['order_type'] == 7:
                            $natal_report_data = [];
                            foreach ($order['data'] as $datum)
                            {
                                $natal_report_data[] = [
                                    'gid' => $datum['gid'],
                                    'title' => $datum['title'],
                                    'rname' => $datum['rname'],
                                    'or_price' => $datum['or_price'],
                                    'now_price' => sprintf('%.2f', $datum['now_price'])
                                ];
                            }
                            $orders_details[$k]['data'] = $natal_report_data;
                            break;
                    }
                }
            }
            $orders['data'] = $orders_details ? array_values($orders_details) : [];
        }
        return show(config('code.success'), '加载成功', $orders);
    }

    /**
     * 接口，获取订单详情
     * @throws Exception
     */
    public function read()
    {
        $param = $this->request->only(['order_id']);
        $validate = validate('Orders');
        //验证请求参数
        if ($validate->scene('read')->check($param) !== true)
        {
            return show(config('code.error'), (string)$validate->getError());
        }

        $orders = (new OrdersCacheModel())->getInfoById($param['order_id']);
        if ($orders)
        {
            if ($orders['uid'] != $this->user['id'])
            {
                Log::write('非法订单查询：' . json_encode($param, true), 'error', true);
                return show(config('code.error'), '服务异常，请稍后重试～');
            }
            $orders_details = (new OrdersLib())->getOrderDetails([$orders]);
            $orders_details = $orders_details ? current($orders_details) : [];
            $data = [
                'status' => $orders_details['status'],
                'count' => $orders_details['count'],
                'or_total_price' => $orders_details['or_total_price'],
                'total_price' => $orders_details['total_price'],
                'trade_type' => $orders_details['trade_type'],
                'order_id' => $orders_details['order_id'],
            ];
            $order_time = [];
            $order_time[] = [
                'name' => '创建时间',
                'value' => $orders_details['create_time']
            ];
            if ($orders_details['pay_time'])
            {
                $order_time[] = [
                    'name' => '支付时间',
                    'value' => $orders_details['pay_time']
                ];
            }
            $data['order'] = $order_time;
            switch (true)
            {
                case in_array((int)$orders_details['status'], [1, 4], true):
                    $data['desc'] = '您购买的相关内容已成功解锁';
                    break;
                case (int)$orders_details['status'] === 2:
                    $data['desc'] = '24小时之内未付款订单自动关闭~';
                    break;
                default:
                    $data['desc'] = '您的订单还没有支付~';
                    break;
            }
            if ($orders_details)
            {
                switch ($orders_details['type'])
                {
                    case 1:
                        break;
                    case 2:
                        $data['fortune'] = $this->FortuneRead($orders_details['fortune_data']);
                        break;
                    case 3:
                        $data['lines'] = $this->MapRead($orders_details['acgmap_data']);
                        break;
                    case 4:
                        $data['video'] = $this->VideoRead($orders_details['video_data']);
                        break;
                    case 5:
                        $data['data'] = $this->NatalReportRead($orders_details['data']);
                        break;
                    default:
                        return [];
                        break;
                }
            }
            return show(config('code.success'), '获取成功', $data);
        }
        return show(config('code.error'), '订单不存在');
    }

    /**
     * 接口，下单
     * goods_type 1=>校准生辰,2=>日运,3=>月运,4=>年运,5=>幸运之城,6=>教学视频,7=>本命预测
     * order_id 01=>校准生辰 02=>运势 03=>幸运之城，04=>教学视频，05=>本命预测
     * @return array|Json
     * @throws Exception
     */
    public function pay_unlock()
    {
        return show(config('code.error'), '请下载最新版APP进行下单');

        $param = request()->only(['rids', 'trade_type', 'gids', 'goods_type']);
        $param['openid'] = input('param.openid', '');
        switch (true)
        {
            case !isset($param['rids']) || !$param['rids']:
                return show(config('code.error'), '缺少档案');
                break;
            case !isset($param['gids']) || !$param['gids']:
                return show(config('code.error'), '缺少商品');
                break;
            // 1=>支付宝,2=>微信支付，5=>京东支付，6=>微信公众号支付 ，7=>支付宝手机网页支付,8=>微信H5网页支付,9=>applePay, 3=>余额支付
            case !isset($param['trade_type']) || !in_array($param['trade_type'], [1, 2, 5, 6, 7, 8, 9]):
                return show(config('code.error'), '当前支付方式不支持');
                break;
            case !isset($param['goods_type']) || !in_array($param['goods_type'], [1, 2, 3, 4, 5, 6, 7]):
                return show(config('code.error'), '未知的商品');
                break;
        }

        $gids = explode(',', $param['gids']);
        $rids = explode(',', $param['rids']);
        //获取购买的商品价格，判断商品是否存在
        $price = $this->OrderGoodsInfo($rids, $gids, $param['goods_type']);
        switch ($price)
        {
            case false:
                return show(config('code.success'), '商品已购买');
                break;
            case 0:
                return show(config('code.success'), '商品不存在');
                break;
        }
        //判断档案是否存在
        $recode = (new Recode())->batchGetInfoByIds($param['rids']);
        if (!$recode)
        {
            return show(config('code.success'), '档案不存在');
        }
        switch (true)
        {
            case $param['goods_type'] == 1:
                $pay_des = '准了 - 校准生辰';
                $type = 1;
                break;
            case in_array($param['goods_type'], [2, 3, 4]):
                $pay_des = '准了 - 运势';
                $type = 2;
                break;
            case $param['goods_type'] == 5:
                $pay_des = '准了 - 幸运之城';
                $type = 3;
                break;
            case $param['goods_type'] == 6:
                $pay_des = '准了 - 教学视频';
                $type = 4;
                break;
            case $param['goods_type'] == 7:
                $pay_des = '准了 - 本命预测';
                $type = 5;
                break;
            default:
                return [];
                break;
        }

        // 生成唯一订单号  011806192149570386 01校准生辰 02运势 03幸运之城 04教学视频 05问答 06围观
        $out_trade_no = str_pad($type, 2, '0', STR_PAD_LEFT) . date('YmdHis') . str_pad(random_int(1, 9999), 4, '0', STR_PAD_LEFT);

        /**
         * $account int 下单使用的商户配置id
         * 支付方式   1=>支付宝，2=>微信支付，5=>京东支付，6=>微信公众号支付，7=>支付宝手机网页支付，8=>微信H5网页支付
         */
        switch ($param['trade_type'])
        {
            case 7:
            case 1:
                $account = (int)config('alipay.default');
                break;
            case 6:
            case 8:
            case 2:
                $account = (int)config('wxpay.default');
                break;
            case 5:
                $account = (int)config('jdpay.default');
                break;
            default:
                $account = 1;
                break;
        }
        $orderModel = new OrdersCacheModel();
        Db::startTrans();
        $res1 = true;
        $res2 = true;
        try
        {
            //生成待支付订单
            $insert = [
                'order_type' => $param['goods_type'],
                'uid' => $this->user['id'],
                'gid' => 0,
                'order_id' => $out_trade_no,
                'reid' => 0,
                'fid' => 0,
                'trade_type' => $param['trade_type'],
                'total_amount' => $price,
                'create_time' => time(),
                'status' => 0,
                'account' => $account
            ];
            //生成订单数据
            $oid = $orderModel->SaveData($insert);
            if ($oid === false)
            {
                $res1 = false;
            }
        }
        catch (Exception $e)
        {
            $res1 = false;
        }

        //若是幸运之城和本命预测生成订单中间表数据
        if (in_array($param['goods_type'], [5, 7]))
        {
            $res2 = $this->InsertOrderGoods($rids, $gids, $oid);
        }
        //更新订单详情缓存
        $orderModel->UpdateCache($out_trade_no, 0);
        if ($res1 && $res2)
        {
            Db::commit();
        } else
        {
            Db::rollback();
        }


        //支付订单
        $arr = (new OrdersLib())->unifyPayOrder([
            'oid' => $oid,
            'trade_type' => $param['trade_type'],
            'total_amount' => $price,
            'pay_des' => $pay_des,
            'order_id' => $out_trade_no,
            'openid' => $param['openid'],
            'callback_url' => '',
            'order_type' => $param['goods_type']
        ], 1);

        $new_gid = [];
        foreach ($gids as $gid)
        {
            $new_gid[] = 'apple_pay_' . $gid;
        }
        $skuId = implode(',', $new_gid);

        if ($this->headers['app-type'] == 'ios')
        {
            $arr['data']['skuId'] = $skuId;
        }

        return show(config('code.success'), '下单成功', $arr['data']);
    }

    /**
     * 运势订单详情
     * @param array $data
     * @return array|Json
     */
    public function FortuneRead($data)
    {
        $arr = [];
        foreach ($data as $datum)
        {
            $arr[] = [
                'id' => $datum['id'],
                'gid' => $datum['gid'],
                'rname' => $datum['rname'],
                'fortune_type' => $datum['fortune_type'],
                'start_time' => $datum['start_time'],
                'end_time' => $datum['end_time'],
                'or_price' => sprintf('%.2f', $datum['or_price']),
                'now_price' => sprintf('%.2f', $datum['now_price']),
            ];
        }
        return $arr;
    }

    /**
     * 幸运之城订单详情
     * @param array $data
     * @return array
     */
    public function MapRead($data)
    {
        $array = [];
        foreach ($data as $datum)
        {
            $array[] = [
                'rid' => $datum['rid'],
                'rname' => $datum['rname'],
                'name' => $datum['gname'],
                'or_price' => sprintf('%.2f', $datum['or_price']),
                'now_price' => sprintf("%.2f", $datum['now_price']),
            ];
        }
        return $array;
    }

    /**
     * 教学视频订单详情
     * @param array $data
     * @return array
     */
    public function VideoRead($data)
    {
        $arr = [];
        foreach ($data as $datum)
        {
            $arr = [
                'id' => $datum['id'],
                'or_price' => sprintf('%.2f', $datum['or_price']),
                'now_price' => sprintf('%.2f', $datum['now_price']),
                'course_name' => '占星课程',
                'course_title' => $datum['course_title'],
            ];
        }
        return $arr;

    }

    /**
     * 本命预测订单详情
     * @param $data
     * @return array
     */
    public function NatalReportRead($data)
    {
        $arr = [];
        foreach ($data as $datum)
        {
            $arr[] = [
                'gid' => $datum['gid'],
                'rid' => $datum['rid'],
                'or_price' => sprintf('%.2f', $datum['or_price']),
                'now_price' => sprintf('%.2f', $datum['now_price']),
                'title' => $datum['title'],
                'rname' => $datum['rname'],
            ];
        }
        return $arr;
    }

    /**
     * 生成订单关联表数据
     * @param $rids
     * @param $gids
     * @param $oid
     * @return bool
     */
    public function InsertOrderGoods($rids, $gids, $oid)
    {
        //生成订单中间表数据
        $order_goods = [];
        foreach ($rids as $rid)
        {
            foreach ($gids as $gid)
            {
                $order_goods[] = [
                    'oid' => $oid,
                    'gid' => $gid,
                    'rid' => $rid
                ];
            }
        }
        try
        {
            //生成订单中间表数据
            (new OrdersGoods())->SaveData($order_goods);
        }
        catch (\Exception $e)
        {
            return false;
        }
        return true;
    }

    /**
     * 获取下单商品信息
     * @param $rids
     * @param $gids
     * @param $order_type
     * @return bool|float|int
     * @throws Exception
     */
    public function OrderGoodsInfo($rids, $gids, $order_type)
    {
        $num = count($rids);
        $price = 0;
        $res = (new OrdersLib())->CheckOrder($this->user['id'], $rids, $gids, $order_type);
        if ($res === false)
        {
            return false;
        }
        //获取商品信息
        $goods = (new Goods())->GoodsTypeInfo($order_type);
        foreach ($goods as $good)
        {
            if (in_array($good['id'], $gids))
            {
                $price += $good['now_prize'];
            }
        }

        return $num * $price;
    }
}
